using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WiiGeeTest
{
  public partial class ThreadSafeTextBox : TextBox
  {
    public ThreadSafeTextBox()
    {
      InitializeComponent();
    }

    #region Text / AppendText
    private delegate void TextDelegate(string text);
    private void SafeSetText(string text)
    {
      base.Text = text;
    }
    public override string Text
    {
      get
      {
        return base.Text;
      }
      set
      {
        if (InvokeRequired)
        {
          TextDelegate callback = SafeSetText;
          BeginInvoke(callback, new object[] { value });
        }
        else
          base.Text = value;
      }
    }

    
    public new void AppendText(string AppendingText)
    {
//      Text += AppendingText;
      if (InvokeRequired)
      {
        TextDelegate callback = AppendText;
        BeginInvoke(callback, new object[] {AppendingText});
        return;
      }

      if (AppendingText.Length > 0)
      {
//        SendMessage(new HandleRef(this, Handle), 0xc5, 0, 0);
        SelectionStart = TextLength;
        SendMessage(new HandleRef(this, Handle), 0xc5, 0, 0);
        SendMessage(new HandleRef(this, Handle), 0xc2, 0, AppendingText);
        SendMessage(new HandleRef(this, Handle), 0xb9, 0, 0);
        ClearUndo();
        SendMessage(new HandleRef(this, Handle), 0xc5, MaxLength, 0);
        
      }
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, string lParam);
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, int lParam);


 

#endregion

    #region Clear method
    private delegate void VoidDelegate();
    public new void Clear()
    {
      if (InvokeRequired)
      {
        VoidDelegate callback = Clear;
        BeginInvoke(callback, new object[] { });
      }
      else
        base.Clear();
    }
    #endregion

    #region Color methods
    private delegate void ColorDelegate(System.Drawing.Color color);
    
    private void ThreadSafeSetBGColor(System.Drawing.Color color)
    {
      base.BackColor = color;
    }
    
    private void ThreadSafeSetFGColor(System.Drawing.Color color)
    {
      base.ForeColor = color;
    }

    public override System.Drawing.Color BackColor
    {
      get
      {
        return base.BackColor;
      }
      set
      {
        if (InvokeRequired)
        {
          ColorDelegate callback = ThreadSafeSetBGColor;
          BeginInvoke(callback, new object[] { value });
        }
        else
          base.BackColor = value;
      }
    }

    public override System.Drawing.Color ForeColor
    {
      get
      {
        return base.ForeColor;
      }
      set
      {
        if (InvokeRequired)
        {
          ColorDelegate callback = ThreadSafeSetFGColor;
          BeginInvoke(callback, new object[] { value });
        }
        else
          base.ForeColor = value;
      }
    }
    #endregion
  }
}

